/********************************************************************/
/*  Copyright (C) School of Software Engineering of USTC, 2012                               
/*                                                                                                                       
/*  FILE NAME: dbapi.c                                                                                          
/*  PRINCIPAL AUTHOR: SA12226114(Xin Zhu), SA12226139(Dan Shu)                    
/*  SUBSYSTEM NAME: DB                                                                                    
/*  MODULE NAME: dbserver.c                                                                                      
/*  LANGUAGE: C                                                                                                 
/*  TARGET ENVIRONMENT: Linux                                                                          
/*  DATE OF FIRST RELEASE: 2012-12-10                                                             
/*  DESCRIPTION: Impement of Abstract Interface for Tokyo Cabinet DB API              
/********************************************************************/


#include "dbserver.h"
#include "dbapi.h"


/*****************************************************************
Function Name: main
Description:
Parameter:  

@argc: argument count
@argv: argument vector

Author: 
Date:  
******************************************************************/
int main(int argc, char** argv)
{
    int listenfd, connfd;
    struct sockaddr_in servaddr;
    int bytes_rev;
    void *db = NULL;

    /* generate a new socket for server end */
    if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
        
        return 0;
    }

    /* initialize structure sockaddr_in with protocol family, ip, port number */
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(10000);

    /* bind socket and socket id */
    if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1)
    {
        printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno);
        
        return 0;
    }

    /* the second parameter is max number of client connection */
    if(listen(listenfd, 100) == -1)
    {
        printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
        
        return 0;
    }

    printf("======waiting for client's messages======\n");
    while(1)
    {
        char cmdline[CMDLINE_LEN], cmd[CMD_LEN], key[KEY_LEN], value[VALUE_LEN];
        
        /* accept messages from client */
        if((connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1)
        {
            printf("accept socket error: %s(errno: %d)", strerror(errno), errno);
            
            continue;
        }

        util_init(cmdline, CMDLINE_LEN);
        util_init(cmd, CMD_LEN);
        util_init(key, KEY_LEN);
        util_init(value, VALUE_LEN);
        

        /* put messages into buffer */
        bytes_rev = recv(connfd, cmdline, CMDLINE_LEN, 0);
        cmdline[bytes_rev] = '\0';
        
        printf("received message is : %s\n", cmdline);

        util_parse(cmdline, CMDLINE_LEN, cmd, key, value);
        util_memset(cmd, CMD_LEN);
        util_memset(key, KEY_LEN);
        util_memset(value, VALUE_LEN);

        
        if(strncmp(cmd, "open", sizeof("open")) == 0)                   /* create database */
        {
            db_create(&db, key);
        }
        else if(strncmp(cmd, "set", sizeof("set")) == 0)                /* store records */
        {
            db_write(db, key, value);
        }
        else if(strncmp(cmd, "get", sizeof("get")) == 0)                /* retrieve records */
        {
            db_read(db, key);
        }
        else if(strncmp(cmd, "remove", sizeof("remove")) == 0)          /* remove a record */
        {
            db_remove(db, key);
        }
        else if(strncmp(cmd, "ls", sizeof("ls")) == 0)                  /* dump all records in database */
        {
            db_queryallrecords(db);
        }
        else if(strncmp(cmd, "close", sizeof("close")) == 0)            /* close the database */
        {
            db_close(&db);
        }
        else if(strncmp(cmd, "delete", sizeof("delete")) == 0)          /* delete the object */
        {
            db_delete(&db);
        }
        else if(strncmp(cmd, "help", sizeof("help")) == 0)              /* display menu info */
        {
            util_menu();
        }
        else if(strncmp(cmd, "quit", sizeof("quit")) == 0)              /* quit system */
        {
            printf("Unknown Command\n");

            return;
        }
        
        close(connfd);
    }

    close(listenfd);
}



